#include "ThreadCache.h"
thread_local ThreadCache* pTLSThreadCache = nullptr;
size_t min(size_t a,size_t b){
    return a<b?a:b;
}
ThreadCache::ThreadCache():_freeLists(MAX_FREELIST){}
void* ThreadCache::FetchFromCentralCache(size_t index,size_t size){
    //获取thread cache中缓存的内存
    //慢开始的反馈调节算法
    //1.最开始不会向centralcache要太多内存，所以初始值是1
    //2.如果你不断要内存，说明你需要的内存多，那么就增加每次获取的内存块数量
    //3.size越小，batchnum越大,size越大，batchnum越小
    size_t batchNum=min(Sizeclass::NumMoveSize(size),_freeLists[index].MaxSize());
    if(batchNum==_freeLists[index].MaxSize()){
        _freeLists[index].MaxSize()+=1;
    }
    void*start=nullptr;
    void*end=nullptr;
    size_t actualNum=CentralCache::getinstance()->FetchRangeObj(start,end,batchNum,size);
    assert(actualNum>0);
    
    if(actualNum==1){
        assert(start==end);
        return start;
    }
    else{
        //取了多个
        _freeLists[index].Pushrange(NextObj(start),end,actualNum-1);
        return start;
    }
}
void* ThreadCache::Allocate(size_t size){
    assert(size<=MAX_BYTEs);
    size_t alignSize=Sizeclass::reoundUp(size);
    size_t index=Sizeclass::Index(size);
    if(!_freeLists[index].Empty()){
        return _freeLists[index].Pop();
    }
    else{
        //没有找中心缓存获取内存
        return FetchFromCentralCache(index,alignSize);
    }
}
void ThreadCache::Deallocate(void* ptr,size_t size){
    assert(ptr);
    assert(size<=MAX_BYTEs);
    //size_t alignSize=Sizeclass::reoundUp(size);
    size_t index=Sizeclass::Index(size);
    //std::cout<<"this deallocate size is "<<_freeLists[index].Size()<<std::endl;
    _freeLists[index].Push(ptr);
    //当链表长度大于依次批量申请的内存时，释放内存给中心缓存
    if(_freeLists[index].Size()>=_freeLists[index].MaxSize()){
        ListTooLong(_freeLists[index],size);
    }
}
void ThreadCache::ListTooLong(FreeList& list,size_t size){
        void* start=nullptr;
        void* end=nullptr;
        list.PopRange(start,end,list.MaxSize());
        CentralCache::getinstance()->ReleaseListSpans(start,size);
}
